﻿using CarPCBATest.Procedure;
using Common;
using MahApps.Metro.Controls;
using MahApps.Metro.Controls.Dialogs;
using Microsoft.Win32;
using NLog.LayoutRenderers;
using OfficeOpenXml;
using System;
using System.Collections.ObjectModel;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using LicenseContext = OfficeOpenXml.LicenseContext;

namespace CarPCBATest.ViewModel
{
    internal class TestResultConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool? result = value as bool?;
            if (parameter.ToString() == "color")
            {
                if (result == true)
                {
                    return Brushes.Green;
                }
                else if (result == false)
                {
                    return Brushes.Red;
                }
                else
                {
                    return Brushes.Gray;
                }
            }
            else
            {
                if (result == true)
                {
                    return "OK";
                }
                else if (result == false)
                {
                    return "NG";
                }
                else
                {
                    return "WAITTING";
                }
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }
    }

    internal class BurnViewModel : NotifyBase
    {
        public ObservableCollection<FlashData> FileFlashData { get; set; }
        public ObservableCollection<FlashData> RegisterFlashData { get; set; }

        private string _chipType;

        public string ChipType
        {
            get { return _chipType; }
            set
            {
                _chipType = value;
                this.DoNotify();
            }
        }

        public BurnViewModel()
        {
            BurnOk = null;
            Port = "COM5";
            Baud = 500000;
            McuAddress = 1;
            FileFlashData = new ObservableCollection<FlashData>();
            RegisterFlashData = new ObservableCollection<FlashData>();

            SelectFileCommand = new CommandBase(SelectFile);
            UnloadedCommand = new CommandBase(Unloaded);
            LoadedCommand = new CommandBase(Loaded);
            WriteFlashCommand = new CommandBase(WriteFlash);
            ReadFlashCommand = new CommandBase(ReadFlash);
        }

        private void WriteFlash(object obj)
        {
            try
            {
                Log = "-------------------" + logIndex++;
                BurnOk = null;
                RegisterFlashData.Clear();
                FileFlashData.Clear();
                Thread.Sleep(10);

                var mwin = Application.Current.MainWindow as MetroWindow;
                if (Port is null | Port == string.Empty)
                {
                    Log = "串口不能为空";
                    return;
                }
                if (EEPRomPath is null | EEPRomPath == string.Empty)
                {
                    Log = "烧录文件不能为空";
                    return;
                }

                if (ChipType == "TPS929120")
                {
                    bool ret = TPS929120.WriteFlash(Port, EEPRomPath, McuAddress, out int newAddress);

                    if (ret)
                    {
                        Log = "烧录完成";
                    }
                    else
                    {
                        Log = "烧录失败";
                        foreach (var item in TPS929120.listErr)
                        {
                            Log = item.ToString();
                        }
                        return;
                    }
                }
                else if (ChipType == "NSL21912")
                {
                    bool ret = NSL21916.WriteFlash(Port, EEPRomPath, McuAddress, out int newAddress);

                    if (ret)
                    {
                        Log = "烧录完成";
                    }
                    else
                    {
                        Log = "烧录失败";
                        foreach (var item in NSL21916.listErr)
                        {
                            Log = item.ToString();
                        }
                        return;
                    }
                }
                else
                {
                    Log = "未知的芯片型号";
                }
            }
            catch (Exception ex)
            {
                Log = ex.Message;
            }
        }

        private void ReadFlash(object obj)
        {
            try
            {
                Log = "-------------------" + logIndex++;
                BurnOk = null;
                RegisterFlashData.Clear();
                FileFlashData.Clear();
                Thread.Sleep(10);

                var mwin = Application.Current.MainWindow as MetroWindow;
                if (Port is null | Port == string.Empty)
                {
                    Log = "串口不能为空";
                    return;
                }
                if (EEPRomPath is null | EEPRomPath == string.Empty)
                {
                    Log = "比对文件不能为空";
                    return;
                }
                if (ChipType == "TPS929120")
                {
                    string checkCode = null;

                    bool ret = TPS929120.ReadFlash(Port, EEPRomPath, McuAddress, out checkCode);

                    Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        for (int i = 0; i < TPS929120.listReadRegReturn.Count; i++)
                        {
                            RegisterFlashData.Add(new FlashData { Index = i, Address = TPS929120.listReadRegReturn[i][2].ToString("X2"), Data = TPS929120.listReadRegReturn[i][4].ToString("X2") });
                            FileFlashData.Add(new FlashData { Index = i, Address = TPS929120.listWriteRegCmd[i + 10][2].ToString("X2"), Data = TPS929120.listWriteRegCmd[i + 10][3].ToString("X2") });
                        }
                    }));

                    Log = "校验码:" + checkCode;
                    BurnOk = ret;
                    if (ret)
                    {
                        Log = "比对OK";
                    }
                    else
                    {
                        Log = "比对NG";
                        foreach (var item in TPS929120.listErr)
                        {
                            Log = item.ToString();
                        }
                        return;
                    }
                }
                else if (ChipType == "NSL21912")
                {
                    string checkCode = null;

                    bool ret = NSL21916.ReadFlash(Port, EEPRomPath, McuAddress, out checkCode);

                    Application.Current.Dispatcher.Invoke(new Action(() =>
                    {
                        for (int i = 0; i < NSL21916.listReadRegReturn.Count; i++)
                        {
                            RegisterFlashData.Add(new FlashData { Index = i, Address = NSL21916.listReadRegReturn[i][2].ToString("X2"), Data = NSL21916.listReadRegReturn[i][4].ToString("X2") });
                            FileFlashData.Add(new FlashData { Index = i, Address = NSL21916.listWriteRegCmd[i + 10][2].ToString("X2"), Data = NSL21916.listWriteRegCmd[i + 10][3].ToString("X2") });
                        }
                    }));

                    Log = "校验码:" + checkCode;
                    BurnOk = ret;
                    if (ret)
                    {
                        Log = "比对OK";
                    }
                    else
                    {
                        Log = "比对NG";
                        foreach (var item in NSL21916.listErr)
                        {
                            Log = item.ToString();
                        }
                        return;
                    }
                }
                else
                {
                    Log = "未知的芯片型号";
                }
            }
            catch (Exception ex)
            {
                Log = ex.Message;
            }
        }

        private void Loaded(object obj)
        {
            PcbConfig config = PcbConfigHelper.GetTestConfig();
            ChipType = config.ChipType;
            Port = config.BurnConfig.Port;
            Baud = config.BurnConfig.Paud;
            McuAddress = config.BurnConfig.SubBurnConfigs[0].McuAddress;
            EEPRomPath = config.BurnConfig.SubBurnConfigs[0].BrunFilePath;
        }

        private void Unloaded(object obj)
        {
        }

        int logIndex = 0;

        private string _log;

        public string Log
        {
            get { return _log; }
            set
            {
                Application.Current.Dispatcher.Invoke(new Action(() =>
                {
                    _log = $"[{logIndex++}][{value}]";
                    this.DoNotify();
                }));
                Console.WriteLine(value);
            }
        }

        private void SelectFile(object obj)
        {
            // 创建一个新的 OpenFileDialog 对象
            OpenFileDialog openFileDialog = new OpenFileDialog();

            // 设置对话框的标题
            openFileDialog.Title = "选择烧录文件";

            openFileDialog.RestoreDirectory = true;

            // 设置过滤器，限制可以选择的文件类型（可选）
            openFileDialog.Filter = "烧录文件 (*.csv)|*.csv|所有文件 (*.*)|*.*";

            // 打开对话框并检查用户是否点击了 "打开" 按钮
            if (openFileDialog.ShowDialog() == true)
            {
                // 用户已选择文件，您可以执行所需的操作
                string selectedFilePath = openFileDialog.FileName;
                Console.WriteLine("选择的文件路径：" + selectedFilePath);
                EEPRomPath = selectedFilePath;
            }
            BurnOk = null;
        }

        private string _port;

        public string Port
        {
            get { return _port; }
            set
            {
                _port = value;
                this.DoNotify();
            }
        }

        private int _baud;

        public int Baud
        {
            get { return _baud; }
            set
            {
                _baud = value;
                this.DoNotify();
            }
        }

        private int _mcuAddress;

        public int McuAddress
        {
            get { return _mcuAddress; }
            set
            {
                _mcuAddress = value;
                this.DoNotify();
            }
        }

        private string _eepromPath;

        public string EEPRomPath
        {
            get { return _eepromPath; }
            set
            {
                _eepromPath = value;
                this.DoNotify();
            }
        }

        private bool? _burnOK;

        public bool? BurnOk
        {
            get { return _burnOK; }
            set
            {
                _burnOK = value;
                this.DoNotify();
            }
        }

        public CommandBase UnloadedCommand { get; set; }
        public CommandBase LoadedCommand { get; set; }
        public CommandBase SelectFileCommand { get; set; }
        public CommandBase ReadFlashCommand { get; set; }
        public CommandBase WriteFlashCommand { get; set; }
        public CommandBase SetPowerCommand { get; set; }

        public CommandBase SetCurrentCommand { get; set; }
    }
}